﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Rhino.Mocks;
using Rhino.Mocks.Constraints;
using SharedGenomics.Workbench.Core;
using SharedGenomics.Workbench.Tests.TestObjects;

namespace SharedGenomics.Workbench.Tests.Core
{
    [TestClass]
    public class DynamicTypeMapperTests
    {
        private Rhino.Mocks.MockRepository mocks;
        private IUnityContainer container;
        private DynamicTypeMapper mapper;

        [TestInitialize]
        public void Setup()
        {
            this.mocks = new Rhino.Mocks.MockRepository();
            this.container = new UnityContainer();

            this.mapper = new DynamicTypeMapper(this.container);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ConstructorShouldThrowIfContainerNull()
        {
            DynamicTypeMapper mapper = new DynamicTypeMapper(null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void AddMappingStrategyShouldThrowIfNull()
        {
            this.mapper.AddMappingStrategy(null);
        }

        [TestMethod]
        public void ShouldCallStrategy()
        {
            ITypeMappingStrategy s1 = this.mocks.StrictMock<ITypeMappingStrategy>();
            this.mapper.AddMappingStrategy(s1);

            using (this.mocks.Record())
            {
                s1.Expect(s => s.ExamineType(null, null))
                    .IgnoreArguments()
                    .Constraints(Is.Equal(typeof(object)), Is.NotNull());
            }

            using (this.mocks.Playback())
            {
                this.mapper.AddMappings(new[] { typeof(object) });
            }
        }

        [TestMethod]
        public void ShouldResolveDynamicDependency()
        {
            this.mapper.AddMappingStrategy<ViewMappingStrategy>();
            this.mapper.AddMappings(new[] { typeof(ExtendedView) });

            var view = this.container.Resolve<IExtendedView>();
        }
    }
}
